package org.jiangwei.cmput696.entitylinking.tacindex;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class TacLuceneIndexer {

	private static final int NGRAM = 2;

	private final TacDocumentPool pool;

	private IndexWriter indexWriter;

	private Thread[] workers;

	private final String indexDir;

//	private class NGramAnalyzer extends Analyzer {
//		private int ngram = 0;
//
//		public NGramAnalyzer(int ngram) {
//			this.ngram = ngram;
//		}
//
//		@Override
//		public TokenStream tokenStream(String fieldName, Reader reader) {
//			return new NGramTokenizer(reader, 2, ngram);
//		}
//	}

	public TacLuceneIndexer(int threadCount, String indexDir,
			TacDocumentPool pool) throws IOException {
		this.pool = pool;
		if (indexDir != null && indexDir.length() > 0) {
			this.indexDir = indexDir;
		} else {
			this.indexDir = TacHelper.DEFAULT_INDEX_DIR;
		}

		// prepare IndexWriter
		Directory dir = null;
		dir = FSDirectory.open(new File(this.indexDir));
		IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_34,
				new StandardAnalyzer(Version.LUCENE_34));
		indexWriter = new IndexWriter(dir, conf);

		workers = new Thread[threadCount];
		for (int i = 0; i < threadCount; i++) {
			workers[i] = new Thread(new WorkerRunnable());
		}
	}

	class WorkerRunnable implements Runnable {
		public void run() {
			while (!pool.isStopped()) {
				Document doc = pool.pop();
				if (doc != null) {
					try {
						indexWriter.addDocument(doc);
					} catch (CorruptIndexException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
				} else {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	public void startWorkers() {
		for (int i = 0; i < workers.length; i++) {
			workers[i].start();
		}
	}

	public void closeWriter() {
		for (int i = 0; i < workers.length; i++) {
			while (workers[i].isAlive()) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// ignore
				}
			}
		}
		try {
			indexWriter.optimize();
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			indexWriter.close();
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
